const mongoose = require('mongoose');
const Cadre = require('../models/Cadre');
const Unit = require('../models/Unit');
const University = require('../models/University');

// This is a unified error handling function to reduce duplicate code
const handleError = (res, error, defaultMessage, statusCode = 500) => {
    // Log detailed errors in the backend console for debugging
    console.error(`[API Error] ${defaultMessage}:`, error);

    // Provide more specific frontend hints for Mongoose validation errors
    if (error.name === 'ValidationError') {
        return res.status(400).json({
            error: '数据验证失败',
            message: error.message,
            details: error.errors
        });
    }
    
    // Check for ObjectId cast errors specifically
    if (error.name === 'CastError' && error.kind === 'ObjectId') {
        return res.status(400).json({
            error: '无效的ID格式',
            message: `提供的ID [${error.value}] 不是一个有效的ObjectId。`
        });
    }

    // Send a generic response for other errors
    res.status(statusCode).json({
        error: defaultMessage,
        message: process.env.NODE_ENV === 'development' ? error.message : '服务器内部错误'
    });
};

const cadrePopulatePaths = [
    { path: 'unitId', select: 'name shortName' },
    { path: 'intendedUniversity1', select: 'schoolName' },
    { path: 'intendedUniversity2', select: 'schoolName' },
    { path: 'intendedUniversity3', select: 'schoolName' },
];

const validateAssociatedIDs = async (body) => {
    const validate = async (model, id, modelName) => {
        if (!id) return;
        if (!mongoose.Types.ObjectId.isValid(id)) {
            throw new Error(`提供的 ${modelName} ID [${id}] 不是一个有效的 ObjectId 格式`);
        }
        if (!(await model.findById(id))) {
            throw new Error(`${modelName} (ID: ${id}) 不存在`);
        }
    };

    await validate(Unit, body.unitId, '所属单位');
    await validate(University, body.intendedUniversity1, '意向高校1');
    await validate(University, body.intendedUniversity2, '意向高校2');
    await validate(University, body.intendedUniversity3, '意向高校3');
};

const getAllCadres = async (req, res) => {
    try {
        const { page = 1, limit = 10, search, unitId, level, cadreType } = req.query;
        const query = {};
        if (search) {
            query.$or = [
                { name: { $regex: search, $options: 'i' } },
                { position: { $regex: search, $options: 'i' } },
                { expertise: { $regex: search, $options: 'i' } }
            ];
        }
        if (unitId) query.unitId = unitId;
        if (level) query.level = level;
        if (cadreType) query.cadreType = cadreType;

        // 处理排序
        let sortObj = { createdAt: -1 }; // 默认排序
        if (req.query.sortBy && req.query.sortOrder) {
            const sortBy = req.query.sortBy;
            const sortOrder = req.query.sortOrder === 'asc' ? 1 : -1;
            sortObj = { [sortBy]: sortOrder };
        }

        const cadres = await Cadre.find(query)
            .populate(cadrePopulatePaths)
            .sort(sortObj)
            .limit(parseInt(limit))
            .skip((parseInt(page) - 1) * parseInt(limit))
            .lean();

        const total = await Cadre.countDocuments(query);

        res.json({
            data: {
                cadres,
                totalPages: Math.ceil(total / limit),
                currentPage: parseInt(page),
                total
            },
            message: '获取干部列表成功'
        });
    } catch (error) {
        handleError(res, error, '获取干部列表失败');
    }
};

const getCadreById = async (req, res) => {
    try {
        const cadre = await Cadre.findById(req.params.id)
            .populate(cadrePopulatePaths)
            .lean();
        if (!cadre) {
            return res.status(404).json({ error: '干部不存在' });
        }
        res.json({
            data: cadre,
            message: '获取干部信息成功'
        });
    } catch (error) {
        handleError(res, error, '获取干部信息失败');
    }
};

const createCadre = async (req, res) => {
    try {
        await validateAssociatedIDs(req.body);
        const newCadre = new Cadre(req.body);
        await newCadre.save();
        const populatedCadre = await Cadre.findById(newCadre._id).populate(cadrePopulatePaths).lean();
        res.status(201).json({
            data: populatedCadre,
            message: '创建干部成功'
        });
    } catch (error) {
        if (error.message.includes('ID') || error.message.includes('不存在')) {
            return handleError(res, error, error.message, 400);
        }
        handleError(res, error, '创建干部失败');
    }
};

const updateCadre = async (req, res) => {
    try {
        await validateAssociatedIDs(req.body);
        const updatedCadre = await Cadre.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true })
            .populate(cadrePopulatePaths)
            .lean();
        if (!updatedCadre) {
            return res.status(404).json({ error: '干部不存在' });
        }
        res.json({
            data: updatedCadre,
            message: '更新干部信息成功'
        });
    } catch (error) {
        if (error.message.includes('ID') || error.message.includes('不存在')) {
            return handleError(res, error, error.message, 400);
        }
        handleError(res, error, '更新干部信息失败');
    }
};

const deleteCadre = async (req, res) => {
    try {
        const deletedCadre = await Cadre.findByIdAndDelete(req.params.id);
        if (!deletedCadre) {
            return res.status(404).json({ error: '干部不存在' });
        }
        res.json({ message: '干部删除成功' });
    } catch (error) {
        handleError(res, error, '删除干部失败');
    }
};

const getTeachingDirections = (req, res) => {
    const directions = ['导论', '新时代坚持和发展中国特色社会主义', '以中国式现代化全面推进中华民族伟大复兴', '坚持党的全面领导', '坚持以人民为中心', '全面深化改革开放', '推动高质量发展', '社会主义现代化建设的教育、科技、人才战略', '发展全过程人民民主', '全面依法治国', '建设社会主义文化强国', '以保障和改善民生为重点加强社会建设', '建设社会主义生态文明', '维护和塑造国家安全', '建设巩固国防和强大人民军队', '坚持"一国两制"和推进祖国完全统一', '中国特色大国外交和推动构建人类命运共同体', '全面从严治党'];
    res.json({
        data: directions,
        message: '获取授课方向成功'
    });
};

// This should be the ONLY export from this file
module.exports = {
    getAllCadres,
    getCadreById,
    createCadre,
    updateCadre,
    deleteCadre,
    getTeachingDirections
};